/*
 * This source code is part of TWaver 4.0
 *
 * Serva Software PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 * Copyright 2002 - 2011 Serva Software. All rights reserved.
 */

package demo.tree.sort;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Comparator;
import java.util.Iterator;

import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.UIManager;

import twaver.Generator;
import twaver.Node;
import twaver.TDataBox;
import twaver.TWaverConst;
import twaver.TWaverUtil;
import twaver.tree.TTree;

class NumberNode extends Node{
	private int value;
	private Color color;
	public NumberNode(){
		this.value = TWaverUtil.getRandomInt(NumberSort.MAX)+1; 
		this.setName(value + "");
	}
	public int getValue(){
		return this.value;
	}
	public void setValue(int value){
		if(value >=0 && value <= NumberSort.MAX && this.value != value){
			int oldValue = this.value;
			this.value = value;
			this.firePropertyChange("value", oldValue, value);
			this.setName(value + "");
		}
	}
	public Color getColor() {
		return color;
	}
	public void setColor(Color color) {
		this.color = color;
	}
}

public class NumberSort extends JPanel{
	public final static int MAX = 20;
	private TDataBox box = new TDataBox("Number Sort Demo");
	private TTree tree = new TTree(box);
	private JCheckBox enableSort = new JCheckBox("Enable Sort");
	private JCheckBox ascend = new JCheckBox("Ascend");
	private JPanel controlPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
	private JButton expand = new JButton("Expand");
	private JButton collapse = new JButton("Collapse");
	private JButton increase = new JButton("Increase");
	private JButton decrease = new JButton("Decrease");
	
	private Comparator comparator = new Comparator(){
		public int compare(Object o1, Object o2) {
			NumberNode n1 = (NumberNode)o1;
			NumberNode n2 = (NumberNode)o2;
			if(ascend.isSelected()){
				return n1.getValue() - n2.getValue();
			}else{
				return n2.getValue() - n1.getValue();
			}
		}
    };
	
	public NumberSort(){
		super(new BorderLayout());
		controlPanel.add(enableSort);
		controlPanel.add(ascend);
		controlPanel.add(expand);
		controlPanel.add(collapse);
		controlPanel.add(increase);
		controlPanel.add(decrease);
		
		this.add(new JScrollPane(tree), BorderLayout.CENTER);
		this.add(controlPanel, BorderLayout.SOUTH);
		
        for (int i = 0; i < 3; i++) {
        	NumberNode node1 = new NumberNode();
            node1.setColor(Color.RED);
            box.addElement(node1);

            for (int j = 0; j < 5; j++) {
            	NumberNode node2 = new NumberNode();
                node2.setParent(node1);
                node2.setColor(Color.YELLOW);
                box.addElement(node2);

                for (int k = 0; k < MAX; k++) {
                	NumberNode node3 = new NumberNode();             
                    node3.setParent(node2);
                    node3.setColor(Color.BLUE);
                    box.addElement(node3);
                }
            }
        }
        enableSort.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e) {
				if(tree.getSortComparator() == null){
					tree.setSortComparator(comparator);
				}else{
					tree.setSortComparator(null);
				}
			}
        });
        ascend.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e) {
				tree.updateTViewUI();
			}
        });
		expand.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e) {
				tree.expandAll();
			}
        });
		collapse.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e) {
				tree.collapseAll();
				tree.expandRoot();
			}
        });
		increase.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e) {
				Iterator it = box.getSelectionModel().selection();
				while(it.hasNext()){
					NumberNode node = (NumberNode)it.next();
					node.setValue(node.getValue()+1);
				}
			}
        });
		decrease.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e) {
				Iterator it = box.getSelectionModel().selection();
				while(it.hasNext()){
					NumberNode node = (NumberNode)it.next();
					node.setValue(node.getValue()-1);
				}
			}
        });		
		tree.setCollapsedIcon(TWaverUtil.getIcon("/demo/sheet/nested/collapse.png"));
		tree.setExpandedIcon(TWaverUtil.getIcon("/demo/sheet/nested/expand.png"));
		
		tree.setUpdateSortOnPropertyChanged(true);
		
		tree.setElementIconGenerator(new Generator(){
			public Object generate(Object object) {
				final NumberNode node = (NumberNode)object;
				Icon icon = new Icon(){
					public int getIconHeight() {
						return 16;
					}
					public int getIconWidth() {
						return 200;
					}
					public void paintIcon(Component c, Graphics g, int x, int y) {
						if(node.isSelected()){
							g.setColor(UIManager.getColor("Tree.selectionBackground"));
							g.fill3DRect(x, y, getIconWidth(), getIconHeight(), true);
							g.setColor(UIManager.getColor("Tree.selectionBorderColor"));
							g.drawRect(x, y, getIconWidth(), getIconHeight());
						}
						g.setColor(node.getColor());
						g.fill3DRect(x+1, y+2, node.getValue() * getIconWidth() / MAX-2, getIconHeight()-4, true);
						((Graphics2D)g).setStroke(TWaverConst.BASIC_STROKE);
						g.setColor(Color.BLACK);
						g.drawRect(x+1, y+2, getIconWidth()-2, getIconHeight()-4);
					}
				};
				return icon;
			}
		});

	}
	
	
}